```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Java String 深度解析 | 技术小馆</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            line-height: 1.8;
            color: #333;
            background-color: #f9fafb;
        }
        h1, h2, h3, h4, h5, h6 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 600;
            color: #111827;
        }
        .code-block {
            font-family: 'Fira Code', 'Courier New', monospace;
            background-color: #f3f4f6;
            border-radius: 0.5rem;
            padding: 1.5rem;
            overflow-x: auto;
            position: relative;
        }
        .code-block::before {
            content: attr(data-lang);
            position: absolute;
            top: 0;
            right: 0;
            background-color: #e5e7eb;
            padding: 0.25rem 0.75rem;
            border-radius: 0 0.5rem 0 0.5rem;
            font-size: 0.875rem;
            color: #6b7280;
        }
        .table-container {
            overflow-x: auto;
            margin: 2rem 0;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            background-color: white;
            border-radius: 0.5rem;
            overflow: hidden;
        }
        th, td {
            padding: 1rem;
            text-align: left;
            border-bottom: 1px solid #e5e7eb;
        }
        th {
            background-color: #f3f4f6;
            font-weight: 600;
        }
        tr:hover {
            background-color: #f9fafb;
        }
        .card {
            background-color: white;
            border-radius: 0.75rem;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            overflow: hidden;
        }
        .card:hover {
            transform: translateY(-4px);
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
        }
        .icon-box {
            width: 3rem;
            height: 3rem;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 0.75rem;
            margin-right: 1rem;
            flex-shrink: 0;
        }
        .section-divider {
            height: 1px;
            background: linear-gradient(90deg, rgba(0,0,0,0) 0%, rgba(156,163,175,0.3) 50%, rgba(0,0,0,0) 100%);
            margin: 4rem 0;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 50%, #9333ea 100%);
        }
        .tooltip {
            position: relative;
        }
        .tooltip-text {
            visibility: hidden;
            width: 200px;
            background-color: #111827;
            color: #fff;
            text-align: center;
            border-radius: 6px;
            padding: 0.5rem;
            position: absolute;
            z-index: 1;
            bottom: 125%;
            left: 50%;
            transform: translateX(-50%);
            opacity: 0;
            transition: opacity 0.3s;
        }
        .tooltip:hover .tooltip-text {
            visibility: visible;
            opacity: 1;
        }
    </style>
</head>
<body class="antialiased">
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-4 sm:px-6 lg:px-8">
        <div class="max-w-5xl mx-auto">
            <div class="flex flex-col md:flex-row items-center">
                <div class="md:w-1/2 mb-10 md:mb-0">
                    <h1 class="text-4xl sm:text-5xl font-bold mb-6 leading-tight">深入理解Java String</h1>
                    <p class="text-xl text-indigo-100 mb-8">揭秘String类的设计哲学与性能奥秘</p>
                    <div class="flex items-center">
                        <div class="bg-white bg-opacity-20 p-3 rounded-full mr-4">
                            <i class="fas fa-code text-2xl"></i>
                        </div>
                        <p class="text-indigo-100">Java开发者必备的核心知识</p>
                    </div>
                </div>
                <div class="md:w-1/2">
                    <div class="bg-white bg-opacity-10 p-8 rounded-xl backdrop-filter backdrop-blur-sm">
                        <h3 class="text-xl font-semibold mb-4">关键知识点</h3>
                        <ul class="space-y-3">
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-300 mt-1 mr-3"></i>
                                <span>String的不可变性设计</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-300 mt-1 mr-3"></i>
                                <span>字符串常量池机制</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-300 mt-1 mr-3"></i>
                                <span>Java 9+的String内存优化</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-300 mt-1 mr-3"></i>
                                <span>StringBuilder与StringBuffer选择</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check-circle text-green-300 mt-1 mr-3"></i>
                                <span>常见陷阱与最佳实践</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
        <!-- Introduction -->
        <section class="mb-16">
            <div class="prose prose-lg max-w-none text-gray-700">
                <p>在 Java 开发世界中，<span class="font-semibold text-indigo-600">String</span> 无疑是使用频率最高的类之一。它看似简单，实则蕴含着丰富的设计思想和性能考量。许多开发者虽然每天都在使用 String，却对其内部机制知之甚少，导致在实际项目中频频出现性能瓶颈。</p>
                <p class="text-xl font-medium text-gray-900 mt-6">如何正确理解和高效使用 String 类，已成为区分初级与高级 Java 开发者的重要指标之一。</p>
            </div>
        </section>

        <!-- Section 1 -->
        <section class="mb-16">
            <div class="flex items-center mb-8">
                <div class="bg-indigo-100 text-indigo-700 icon-box">
                    <i class="fas fa-book-open text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold">一、String 基础知识</h2>
            </div>

            <!-- Subsection 1.1 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">1.1 String 的本质</h3>
                <p class="mb-6">在 Java 中，String 是一个<span class="font-semibold text-indigo-600">不可变（immutable）</span>的 final 类，它内部使用一个字符数组来存储字符序列。</p>
                
                <div class="code-block mb-6" data-lang="java">
                    public final class String
                        implements java.io.Serializable, Comparable<String>, CharSequence {
                        /** The value is used for character storage. */
                        private final char[] value;  // Java 8 及之前的实现
                        
                        // Java 9 之后改为了byte[]数组 + coder字段
                        // private final byte[] value;
                        // private final byte coder;
                    }
                </div>
                
                <div class="card p-6 mb-6">
                    <p class="font-medium text-gray-700 mb-2 flex items-center">
                        <i class="fas fa-info-circle text-indigo-500 mr-2"></i>
                        <span>关键概念</span>
                    </p>
                    <p>不可变性意味着 String 对象一旦创建，就不能被修改。每次对 String 的修改操作（如连接、截取等）都会创建一个新的 String 对象，而原对象保持不变。</p>
                </div>
            </article>

            <!-- Subsection 1.2 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">1.2 String 的创建方式</h3>
                <p class="mb-6">Java 中创建 String 对象主要有两种方式：</p>
                
                <div class="grid md:grid-cols-2 gap-6 mb-8">
                    <div class="card p-6">
                        <h4 class="font-semibold text-lg mb-3">字面量方式（String Literal）</h4>
                        <div class="code-block mb-4" data-lang="java">
                            String str1 = "Hello";
                            String str2 = "Hello";  // str1 和 str2 引用同一个对象
                        </div>
                        <p>使用字面量方式创建的字符串会被放入字符串常量池（String Pool），如果常量池中已存在相同内容的字符串，则直接返回其引用，不会创建新对象。</p>
                    </div>
                    
                    <div class="card p-6">
                        <h4 class="font-semibold text-lg mb-3">使用 new 关键字</h4>
                        <div class="code-block mb-4" data-lang="java">
                            String str3 = new String("Hello");  // 强制创建新对象
                        </div>
                        <p>使用 new 关键字会强制在堆内存中创建一个新的 String 对象，即使内容相同也会创建新对象。</p>
                    </div>
                </div>
            </article>

            <!-- Subsection 1.3 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">1.3 字符串常量池</h3>
                <p class="mb-6">字符串常量池是 JVM 内存中的一个特殊区域，用于存储字符串字面量。它的设计目的是为了提高性能和减少内存消耗，通过共享相同内容的字符串对象来实现这些目标。</p>
                
                <div class="code-block mb-6" data-lang="java">
                    public class StringPoolDemo {
                        public static void main(String[] args) {
                            // 字符串字面量，直接进入常量池
                            String s1 = "Hello";
                            String s2 = "Hello";
                            
                            // 使用new关键字，会在堆上创建对象
                            String s3 = new String("Hello");
                            
                            // 使用intern()方法将字符串放入常量池
                            String s4 = s3.intern();
                            
                            // 比较引用是否相同
                            System.out.println("s1 == s2: " + (s1 == s2));  // true
                            System.out.println("s1 == s3: " + (s1 == s3));  // false
                            System.out.println("s1 == s4: " + (s1 == s4));  // true
                            
                            // 比较内容是否相同
                            System.out.println("s1.equals(s3): " + s1.equals(s3));  // true
                        }
                    }
                </div>
                
                <div class="card p-6 bg-blue-50 border-blue-200">
                    <div class="flex items-start">
                        <div class="flex-shrink-0">
                            <i class="fas fa-lightbulb text-blue-500 text-xl mr-3 mt-1"></i>
                        </div>
                        <div>
                            <h4 class="font-semibold text-lg mb-2 text-blue-800">性能提示</h4>
                            <p class="text-blue-700">对于大量重复的字符串，可以使用 <code class="bg-blue-100 px-1 py-0.5 rounded">intern()</code> 方法将它们放入字符串常量池，从而减少内存使用。但要注意，过度使用可能会增加常量池的负担。</p>
                        </div>
                    </div>
                </div>
            </article>
        </section>

        <div class="section-divider"></div>

        <!-- Section 2 -->
        <section class="mb-16">
            <div class="flex items-center mb-8">
                <div class="bg-purple-100 text-purple-700 icon-box">
                    <i class="fas fa-tachometer-alt text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold">二、String 内部实现与性能优化</h2>
            </div>

            <!-- Subsection 2.1 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">2.1 从 char[] 到 byte[]</h3>
                <p class="mb-6">在 Java 9 之前，String 内部使用 char[] 数组存储字符：</p>
                
                <div class="code-block mb-6" data-lang="java">
                    // Java 8 中的String实现
                    private final char[] value;
                </div>
                
                <p class="mb-6">而从 Java 9 开始，String 的内部实现发生了变化，改为使用 byte[] 数组加上一个编码标记：</p>
                
                <div class="code-block mb-6" data-lang="java">
                    // Java 9+ 中的String实现
                    private final byte[] value;
                    private final byte coder;  // 0表示Latin-1编码，1表示UTF-16编码
                </div>
                
                <div class="card p-6 bg-purple-50 border-purple-200">
                    <p class="font-medium text-purple-800 mb-4">这一变化主要是为了节省内存。在实际应用中，大多数字符串只包含ASCII字符，每个字符只需要1字节就能表示，而 char 需要2字节。通过使用 byte[] 和编码标记，Java 9 的 String 实现可以在适当情况下节省一半的内存。</p>
                </div>
            </article>

            <!-- Subsection 2.2 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">2.2 String 的不可变性及其好处</h3>
                <p class="mb-6">String 的不可变性是它最重要的特性之一，这带来了诸多好处：</p>
                
                <div class="grid md:grid-cols-2 gap-6 mb-8">
                    <div class="card p-6">
                        <h4 class="font-semibold text-lg mb-3 flex items-center">
                            <i class="fas fa-lock text-green-500 mr-2"></i>
                            <span>安全性</span>
                        </h4>
                        <p>字符串经常用于存储敏感信息，不可变性确保这些信息不会被意外修改</p>
                    </div>
                    
                    <div class="card p-6">
                        <h4 class="font-semibold text-lg mb-3 flex items-center">
                            <i class="fas fa-users text-blue-500 mr-2"></i>
                            <span>线程安全</span>
                        </h4>
                        <p>不可变对象天然线程安全，多线程环境下可以安全共享</p>
                    </div>
                    
                    <div class="card p-6">
                        <h4 class="font-semibold text-lg mb-3 flex items-center">
                            <i class="fas fa-bolt text-yellow-500 mr-2"></i>
                            <span>哈希缓存</span>
                        </h4>
                        <p>String 的 hashCode() 方法会缓存计算结果，提高在 HashMap、HashSet 中的性能</p>
                    </div>
                    
                    <div class="card p-6">
                        <h4 class="font-semibold text-lg mb-3 flex items-center">
                            <i class="fas fa-database text-purple-500 mr-2"></i>
                            <span>字符串池优化</span>
                        </h4>
                        <p>由于字符串不可变，可以安全地在常量池中共享相同内容的字符串</p>
                    </div>
                </div>
                
                <div class="bg-yellow-50 border-l-4 border-yellow-400 p-4 mb-6">
                    <div class="flex">
                        <div class="flex-shrink-0">
                            <i class="fas fa-exclamation-triangle text-yellow-500 mt-1 mr-3"></i>
                        </div>
                        <div>
                            <p class="text-yellow-700">看起来很美好，但不可变性也带来了性能问题，特别是在频繁进行字符串连接操作时。</p>
                        </div>
                    </div>
                </div>
            </article>

            <!-- Subsection 2.3 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">2.3 性能优化：StringBuilder vs StringBuffer</h3>
                <p class="mb-6">当需要频繁修改字符串内容时，使用 String 会导致过多的中间对象创建，影响性能和内存使用。Java 提供了 StringBuilder 和 StringBuffer 来解决这个问题：</p>
                
                <div class="code-block mb-6" data-lang="java">
                    public class StringBuilderPerformance {
                        public static void main(String[] args) {
                            int iterations = 100000;
                            
                            // 使用String连接字符串
                            long startTime = System.currentTimeMillis();
                            String result = "";
                            for (int i = 0; i < iterations; i++) {
                                result += "a";
                            }
                            long endTime = System.currentTimeMillis();
                            System.out.println("String连接耗时: " + (endTime - startTime) + "ms");
                            
                            // 使用StringBuilder连接字符串
                            startTime = System.currentTimeMillis();
                            StringBuilder sb = new StringBuilder();
                            for (int i = 0; i < iterations; i++) {
                                sb.append("a");
                            }
                            result = sb.toString();
                            endTime = System.currentTimeMillis();
                            System.out.println("StringBuilder连接耗时: " + (endTime - startTime) + "ms");
                            
                            // 使用StringBuffer连接字符串
                            startTime = System.currentTimeMillis();
                            StringBuffer buffer = new StringBuffer();
                            for (int i = 0; i < iterations; i++) {
                                buffer.append("a");
                            }
                            result = buffer.toString();
                            endTime = System.currentTimeMillis();
                            System.out.println("StringBuffer连接耗时: " + (endTime - startTime) + "ms");
                        }
                    }
                </div>
                
                <h4 class="text-xl font-semibold mb-4 mt-8">区别对比：</h4>
                <div class="table-container">
                    <table>
                        <thead>
                            <tr>
                                <th>类名</th>
                                <th>可变性</th>
                                <th>线程安全</th>
                                <th>性能</th>
                                <th>适用场景</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td>String</td>
                                <td>不可变</td>
                                <td>是</td>
                                <td>较低</td>
                                <td>字符串内容不频繁变化的场景</td>
                            </tr>
                            <tr>
                                <td>StringBuilder</td>
                                <td>可变</td>
                                <td>否</td>
                                <td>最高</td>
                                <td>单线程环境下频繁修改字符串</td>
                            </tr>
                            <tr>
                                <td>StringBuffer</td>
                                <td>可变</td>
                                <td>是</td>
                                <td>中等</td>
                                <td>多线程环境下修改字符串</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </article>

            <!-- Subsection 2.4 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">2.4 字符串拼接的编译器优化</h3>
                <p class="mb-6">在日常编码中，我们经常会看到这样的代码：</p>
                
                <div class="code-block mb-6" data-lang="java">
                    String s = "Hello" + " " + "World";
                </div>
                
                <p class="mb-6">这看起来像是使用了 "+" 进行字符串连接，但实际上编译器会对其进行优化，在编译时就将其转换为：</p>
                
                <div class="code-block mb-6" data-lang="java">
                    String s = "Hello World";
                </div>
                
                <p class="mb-6">同样，对于包含变量的字符串连接，编译器也会进行优化，将其转换为 StringBuilder 操作：</p>
                
                <div class="code-block mb-6" data-lang="java">
                    String a = "Hello";
                    String b = a + " World";  // 编译器转换为 new StringBuilder().append(a).append(" World").toString()
                </div>
                
                <div class="bg-red-50 border-l-4 border-red-400 p-4 mb-6">
                    <div class="flex">
                        <div class="flex-shrink-0">
                            <i class="fas fa-exclamation-circle text-red-500 mt-1 mr-3"></i>
                        </div>
                        <div>
                            <h4 class="font-medium text-red-800 mb-2">重要警告</h4>
                            <p class="text-red-700">在循环中进行字符串连接时，编译器的优化是有限的：</p>
                            <div class="code-block mt-2" data-lang="java">
                                String result = "";
                                for (int i = 0; i < 100; i++) {
                                    result += i;  // 每次循环都会创建新的StringBuilder对象！
                                }
                            </div>
                        </div>
                    </div>
                </div>
                
                <p class="mb-4">上面的代码在每次循环迭代中都会创建一个新的 StringBuilder 对象，仍然会导致性能问题。正确的做法是：</p>
                
                <div class="code-block mb-6" data-lang="java">
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < 100; i++) {
                        sb.append(i);
                    }
                    String result = sb.toString();
                </div>
            </article>
        </section>

        <div class="section-divider"></div>

        <!-- Section 3 -->
        <section class="mb-16">
            <div class="flex items-center mb-8">
                <div class="bg-green-100 text-green-700 icon-box">
                    <i class="fas fa-tools text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold">三、String 的常用方法与实战技巧</h2>
            </div>

            <!-- Subsection 3.1 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">3.1 核心 API 解析</h3>
                <p class="mb-6">String 类提供了丰富的方法，以下是最常用的一些：</p>
                
                <div class="code-block mb-6" data-lang="java">
                    public class StringMethodsDemo {
                        public static void main(String[] args) {
                            String str = "  Hello, Java World!  ";
                            
                            // 长度和判空
                            System.out.println("长度: " + str.length());
                            System.out.println("是否为空: " + str.isEmpty());
                            
                            // 去除空白
                            System.out.println("去除两端空白: [" + str.trim() + "]");
                            
                            // 查找子串
                            System.out.println("Java的位置: " + str.indexOf("Java"));
                            System.out.println("是否包含World: " + str.contains("World"));
                            
                            // 提取子串
                            System.out.println("提取子串: " + str.substring(9, 13));  // Java
                            
                            // 替换
                            System.out.println("替换: " + str.replace("Java", "Python"));
                            
                            // 大小写转换
                            System.out.println("转小写: " + str.toLowerCase());
                            System.out.println("转大写: " + str.toUpperCase());
                            
                            // 拆分
                            String[] parts = str.split(",");
                            System.out.println("拆分后的第二部分: " + parts[1]);
                            
                            // 判断开头和结尾
                            System.out.println("是否以Hello开头: " + str.trim().startsWith("Hello"));
                            System.out.println("是否以!结尾: " + str.trim().endsWith("!"));
                            
                            // 格式化字符串
                            String formatted = String.format("名字: %s, 年龄: %d", "张三", 25);
                            System.out.println(formatted);
                            
                            // Java 11+的方法
                            // System.out.println("去除前导和尾随空白: [" + str.strip() + "]");
                            // System.out.println("重复字符串: " + "abc".repeat(3));
                            // System.out.println("判断是否为空白: " + "   ".isBlank());
                        }
                    }
                </div>
            </article>

            <!-- Subsection 3.2 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">3.2 实战技巧：字符串处理最佳实践</h3>
                
                <div class="mb-12">
                    <h4 class="text-xl font-semibold mb-4 text-gray-800">3.2.1 避免空指针异常</h4>
                    <div class="code-block mb-6" data-lang="java">
                        public class StringNullSafeDemo {
                            public static void main(String[] args) {
                                String nullStr = null;
                                String emptyStr = "";
                                
                                // 错误方式：可能导致NullPointerException
                                // if (nullStr.equals("some value")) { ... }
                                
                                // 正确方式：使用常量调用equals方法
                                if ("some value".equals(nullStr)) {
                                    System.out.println("相等");
                                } else {
                                    System.out.println("不相等");
                                }
                                
                                // 使用Objects.equals
                                if (java.util.Objects.equals(nullStr, "some value")) {
                                    System.out.println("相等");
                                } else {
                                    System.out.println("不相等");
                                }
                                
                                // 检查空字符串
                                boolean isNullOrEmpty = nullStr == null || nullStr.isEmpty();
                                System.out.println("nullStr是否为null或空: " + isNullOrEmpty);
                                
                                boolean isEmptyOrNull = emptyStr == null || emptyStr.isEmpty();
                                System.out.println("emptyStr是否为null或空: " + isEmptyOrNull);
                            }
                        }
                    </div>
                </div>
                
                <div class="mb-12">
                    <h4 class="text-xl font-semibold mb-4 text-gray-800">3.2.2 高效字符串连接</h4>
                    <p class="mb-4">在实际项目中，我们经常需要构建比较复杂的字符串，如SQL语句、JSON等：</p>
                    <div class="code-block mb-6" data-lang="java">
                        public class StringConcatenationDemo {
                            public static void main(String[] args) {
                                // 构建SQL查询
                                String[] columns = {"id", "name", "age", "email"};
                                String[] conditions = {"age > 18", "department = 'IT'"};
                                
                                // 使用StringBuilder构建查询
                                StringBuilder sqlBuilder = new StringBuilder();
                                sqlBuilder.append("SELECT ");
                                
                                // 添加列名
                                for (int i = 0; i < columns.length; i++) {
                                    sqlBuilder.append(columns[i]);
                                    if (i < columns.length - 1) {
                                        sqlBuilder.append(", ");
                                    }
                                }
                                
                                sqlBuilder.append(" FROM users WHERE ");
                                
                                // 添加条件
                                for (int i = 0; i < conditions.length; i++) {
                                    sqlBuilder.append(conditions[i]);
                                    if (i < conditions.length - 1) {
                                        sqlBuilder.append(" AND ");
                                    }
                                }
                                
                                String sql = sqlBuilder.toString();
                                System.out.println("生成的SQL: " + sql);
                                
                                // 构建JSON
                                StringBuilder jsonBuilder = new StringBuilder();
                                jsonBuilder.append("{");
                                jsonBuilder.append("\"name\": \"张三\", ");
                                jsonBuilder.append("\"age\": 25, ");
                                jsonBuilder.append("\"skills\": [\"Java\", \"Python\", \"JavaScript\"]");
                                jsonBuilder.append("}");
                                
                                String json = jsonBuilder.toString();
                                System.out.println("生成的JSON: " + json);
                            }
                        }
                    </div>
                </div>
                
                <div class="mb-12">
                    <h4 class="text-xl font-semibold mb-4 text-gray-800">3.2.3 String.intern() 优化</h4>
                    <p class="mb-4">在处理大量重复字符串时，可以使用 String.intern() 方法来减少内存使用：</p>
                    <div class="code-block mb-6" data-lang="java">
                        public class StringInternDemo {
                            public static void main(String[] args) {
                                // 模拟从数据库读取的1000条记录，每条记录有一个状态字段
                                // 实际中状态可能只有几种，如"活跃"、"禁用"、"待审核"等
                                String[] statuses = {"active", "inactive", "pending", "suspended", "deleted"};
                                String[] records = new String[1000];
                                
                                // 使用随机状态填充记录
                                java.util.Random random = new java.util.Random();
                                for (int i = 0; i < records.length; i++) {
                                    // 模拟从数据库读取的字符串（每次都是新对象）
                                    String status = new String(statuses[random.nextInt(statuses.length)]);
                                    records[i] = status;
                                }
                                
                                // 统计不使用intern的内存占用
                                int uniqueObjectsWithoutIntern = countUniqueObjects(records);
                                System.out.println("不使用intern的唯一对象数: " + uniqueObjectsWithoutIntern);
                                
                                // 使用intern
                                for (int i = 0; i < records.length; i++) {
                                    records[i] = records[i].intern();
                                }
                                
                                // 统计使用intern后的内存占用
                                int uniqueObjectsWithIntern = countUniqueObjects(records);
                                System.out.println("使用intern后的唯一对象数: " + uniqueObjectsWithIntern);
                            }
                            
                            private static int countUniqueObjects(String[] strings) {
                                java.util.Set<String> uniqueReferences = java.util.Collections.newSetFromMap(
                                    new java.util.IdentityHashMap<>());
                                uniqueReferences.addAll(java.util.Arrays.asList(strings));
                                return uniqueReferences.size();
                            }
                        }
                    </div>
                </div>
            </article>
        </section>

        <div class="section-divider"></div>

        <!-- Section 4 -->
        <section class="mb-16">
            <div class="flex items-center mb-8">
                <div class="bg-red-100 text-red-700 icon-box">
                    <i class="fas fa-exclamation-triangle text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold">四、String 的常见陷阱与解决方案</h2>
            </div>

            <!-- Subsection 4.1 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">4.1 字符串比较：== vs equals()</h3>
                <div class="code-block mb-6" data-lang="java">
                    public class StringComparisonDemo {
                        public static void main(String[] args) {
                            String str1 = "Hello";
                            String str2 = "Hello";
                            String str3 = new String("Hello");
                            String str4 = str3.intern();
                            
                            System.out.println("str1 == str2: " + (str1 == str2));  // true
                            System.out.println("str1 == str3: " + (str1 == str3));  // false
                            System.out.println("str1 == str4: " + (str1 == str4));  // true
                            
                            System.out.println("str1.equals(str2): " + str1.equals(str2));  // true
                            System.out.println("str1.equals(str3): " + str1.equals(str3));  // true
                            
                            // 注意空字符串和null的比较
                            String nullStr = null;
                            
                            // 下面的代码会抛出NPE
                            // System.out.println(nullStr.equals(""));
                            
                            // 安全的比较方式
                            System.out.println("".equals(nullStr));  // false
                        }
                    }
                </div>
            </article>

            <!-- Subsection 4.2 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">4.2 正则表达式陷阱</h3>
                <p class="mb-6">String 的 replaceAll 方法使用正则表达式，这常常成为性能陷阱：</p>
                
                <div class="code-block mb-6" data-lang="java">
                    public class RegexPerformanceDemo {
                        public static void main(String[] args) {
                            String text = "Hello, my phone number is 123-456-7890. Call me!";
                            
                            // 需要转义特殊字符
                            long startTime = System.currentTimeMillis();
                            for (int i = 0; i < 100000; i++) {
                                // 错误用法：不小心使用了正则表达式特殊字符
                                text.replaceAll(".", "*");  // . 在正则中匹配任意字符
                            }
                            long endTime = System.currentTimeMillis();
                            System.out.println("错误的replaceAll耗时: " + (endTime - startTime) + "ms");
                            
                            // 正确方式：转义特殊字符
                            startTime = System.currentTimeMillis();
                            for (int i = 0; i < 100000; i++) {
                                text.replaceAll("\\.", "*");
                            }
                            endTime = System.currentTimeMillis();
                            System.out.println("正确的replaceAll耗时: " + (endTime - startTime) + "ms");
                            
                            // 不需要正则时，使用replace更高效
                            startTime = System.currentTimeMillis();
                            for (int i = 0; i < 100000; i++) {
                                text.replace(".", "*");
                            }
                            endTime = System.currentTimeMillis();
                            System.out.println("使用replace耗时: " + (endTime - startTime) + "ms");
                        }
                    }
                </div>
            </article>

            <!-- Subsection 4.3 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">4.3 字符串分割的性能问题</h3>
                <div class="code-block mb-6" data-lang="java">
                    public class StringSplitPerformanceDemo {
                        public static void main(String[] args) {
                            String longText = generateCommaDelimitedString(1000);
                            
                            // 使用String.split()
                            long startTime = System.currentTimeMillis();
                            for (int i = 0; i < 10000; i++) {
                                String[] parts = longText.split(",");
                            }
                            long endTime = System.currentTimeMillis();
                            System.out.println("String.split()耗时: " + (endTime - startTime) + "ms");
                            
                            // 使用StringTokenizer
                            startTime = System.currentTimeMillis();
                            for (int i = 0; i < 10000; i++) {
                                java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(longText, ",");
                                while (tokenizer.hasMoreTokens()) {
                                    String token = tokenizer.nextToken();
                                }
                            }
                            endTime = System.currentTimeMillis();
                            System.out.println("StringTokenizer耗时: " + (endTime - startTime) + "ms");
                        }
                        
                        private static String generateCommaDelimitedString(int itemCount) {
                            StringBuilder sb = new StringBuilder();
                            for (int i = 0; i < itemCount; i++) {
                                sb.append("item").append(i);
                                if (i < itemCount - 1) {
                                    sb.append(",");
                                }
                            }
                            return sb.toString();
                        }
                    }
                </div>
            </article>

            <!-- Subsection 4.4 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">4.4 内存泄漏问题</h3>
                <p class="mb-6">大型字符串的子字符串操作可能导致内存泄漏：</p>
                
                <div class="code-block mb-6" data-lang="java">
                    public class SubstringMemoryLeakDemo {
                        public static void main(String[] args) {
                            String largeString = new String(new char[1000000]);  // 创建一个包含100万个字符的字符串
                            
                            // 在Java 7以前，这会导致内存泄漏，因为smallString会持有largeString的整个字符数组
                            String smallString = largeString.substring(0, 2);
                            
                            System.out.println("小字符串长度: " + smallString.length());
                            
                            // 解决方案（Java 7之前需要）：创建新的字符串对象
                            String safeSmallString = new String(smallString);
                            System.out.println("安全的小字符串长度: " + safeSmallString.length());
                            
                            // 注：从Java 7开始，substring不再共享原字符串的底层字符数组，所以不会发生内存泄漏
                        }
                    }
                </div>
            </article>
        </section>

        <div class="section-divider"></div>

        <!-- Section 5 -->
        <section class="mb-16">
            <div class="flex items-center mb-8">
                <div class="bg-indigo-100 text-indigo-700 icon-box">
                    <i class="fas fa-user-tie text-xl"></i>
                </div>
                <h2 class="text-3xl font-bold">五、面试与工程实践中的 String</h2>
            </div>

            <!-- Subsection 5.1 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">5.1 常见面试题解析</h3>
                
                <div class="mb-12">
                    <h4 class="text-xl font-semibold mb-4 text-gray-800">5.1.1 字符串常量池相关问题</h4>
                    <div class="code-block mb-6" data-lang="java">
                        public class StringInterviewDemo {
                            public static void main(String[] args) {
                                // 问题1：下面的代码会创建几个字符串对象？
                                String s1 = "Hello";
                                String s2 = "Hello";
                                String s3 = "Hel" + "lo";
                                String s4 = "Hel" + new String("lo");
                                String s5 = new String("Hello");
                                String s6 = s5.intern();
                                String s7 = "H";
                                String s8 = s7 + "ello";
                                
                                System.out.println("s1 == s2: " + (s1 == s2));  // true
                                System.out.println("s1 == s3: " + (s1 == s3));  // true
                                System.out.println("s1 == s4: " + (s1 == s4));  // false
                                System.out.println("s1 == s5: " + (s1 == s5));  // false
                                System.out.println("s1 == s6: " + (s1 == s6));  // true
                                System.out.println("s1 == s8: " + (s1 == s8));  // false
                            }
                        }
                    </div>
                </div>
                
                <div class="mb-12">
                    <h4 class="text-xl font-semibold mb-4 text-gray-800">5.1.2 编写一个函数，判断两个字符串是否是字母异位词</h4>
                    <div class="code-block mb-6" data-lang="java">
                        public class AnagramCheck {
                            public static void main(String[] args) {
                                String str1 = "listen";
                                String str2 = "silent";
                                
                                System.out.println("是否为字母异位词: " + isAnagram(str1, str2));
                            }
                            
                            public static boolean isAnagram(String s1, String s2) {
                                if (s1 == null || s2 == null || s1.length() != s2.length()) {
                                    return false;
                                }
                                
                                // 方法1：排序比较
                                char[] chars1 = s1.toCharArray();
                                char[] chars2 = s2.toCharArray();
                                java.util.Arrays.sort(chars1);
                                java.util.Arrays.sort(chars2);
                                
                                return java.util.Arrays.equals(chars1, chars2);
                                
                                // 方法2：字符计数
                                /*
                                int[] counter = new int[26];
                                
                                for (int i = 0; i < s1.length(); i++) {
                                    counter[s1.charAt(i) - 'a']++;
                                    counter[s2.charAt(i) - 'a']--;
                                }
                                
                                for (int count : counter) {
                                    if (count != 0) {
                                        return false;
                                    }
                                }
                                
                                return true;
                                */
                            }
                        }
                    </div>
                </div>
            </article>

            <!-- Subsection 5.2 -->
            <article class="mb-12">
                <h3 class="text-2xl font-semibold mb-6 text-gray-800">5.2 工程实践中的优化案例</h3>
                
                <h4 class="text-xl font-semibold mb-4 text-gray-800">5.2.1 日志输出优化</h4>
                <p class="mb-6">在日志记录中，我们经常需要拼接字符串，但在某些情况下，这些日志可能根本不会被输出（如调试级别日志在生产环境）：</p>
                
                <div class="code-block mb-6" data-lang="java">
                    public class LoggingOptimizationDemo {
                        // 模拟日志级别
                        private static final int DEBUG = 1;
                        private static final int INFO = 2;
                        private static final int WARN = 3;
                        private static final int ERROR = 4;
                        
                        // 当前日志级别
                        private static int currentLogLevel = INFO;
                        
                        public static void main(String[] args) {
                            User user = new User("张三", 25);
                            
                            // 错误方式：即使日志不会输出，也会执行字符串拼接
                            long startTime = System.currentTimeMillis();
                            for (int i = 0; i < 1000000; i++) {
                                debug("用户信息: " + user.getName() + ", 年龄: " + user.getAge() + ", ID: " + generateUserId(user));
                            }
                            long endTime = System.currentTimeMillis();
                            System.out.println("错误方式耗时: " + (endTime - startTime) + "ms");
                            
                            // 正确方式：使用lambda表达式延迟计算
                            startTime = System.currentTimeMillis();
                            for (int i = 0; i < 1000000; i++) {
                                debugLambda(() -> "用户信息: " + user.getName() + ", 年龄: " + user.getAge() + ", ID: " + generateUserId(user));
                            }
                            endTime = System.currentTimeMillis();
                            System.out.println("正确方式耗时: " + (endTime - startTime) + "ms");
                        }
                        
                        // 错误方式
                        public static void debug(String message) {
                            if (currentLogLevel <= DEBUG) {
                                System.out.println("[DEBUG] " + message);
                            }
                        }
                        
                        // 正确方式
                        public static void debugLambda(java.util.function.Supplier<String> messageSupplier) {
                            if (currentLogLevel <= DEBUG) {
                                System.out.println("[DEBUG] " + messageSupplier.get());
                            }
                        }
                        
                        // 模拟一个耗时的操作
                        private static String generateUserId(User user) {
                            try {
                                Thread.sleep(1);  // 模拟耗时操作
                            } catch (InterruptedException e) {
                                Thread.currentThread().interrupt();
                            }
                            return "UID" + user.getName().hashCode();
                        }
                        
                        // 用户类
                        static class User {
                            private String name;
                            private int age;
                            
                            public User(String name, int age) {
                                this.name = name;
                                this.age = age;
                            }
                            
                            public String getName() {
                                return name;
                            }
                            
                            public int getAge() {
                                return age;
                            }
                        }
                    }
                </div>
            </article>
        </section>

        <!-- Footer -->
        <footer class="bg-gray-900 text-white py-12 px-4 sm:px-6 lg:px-8">
            <div class="max-w-5xl mx-auto">
                <div class="flex flex-col md:flex-row justify-between items-center">
                    <div class="mb-6 md:mb-0">
                        <h3 class="text-xl font-bold mb-2">技术小馆</h3>
                        <p class="text-gray-400">探索编程之美，分享技术精华</p>
                    </div>
                    <div>
                        <a href="http://www.yuque.com/jtostring" class="text-indigo-400 hover:text-indigo-300 transition-colors duration-300 flex items-center">
                            <i class="fas fa-external-link-alt mr-2"></i>
                            <span>访问我们的语雀知识库</span>
                        </a>
                    </div>
                </div>
            </div>
        </footer>

        <script>
            mermaid.initialize({
                startOnLoad: true,
                theme: 'default',
                flowchart: {
                    useMaxWidth: false,
                    htmlLabels: true,
                    curve: 'basis'
                }
            });
        </script>
    </main>
</body>
</html>
```